# filepath: d:\CompanyProject\Gitee\DBCompareX\backend\app\routers\task_data_sync\execution_log.py
from fastapi import APIRouter, Body, Query, Depends, HTTPException
from fastapi.responses import StreamingResponse
from typing import Optional, Dict, Any, List
import io
from openpyxl import Workbook
from openpyxl.styles import PatternFill

from ...models.task_data_sync.execution import TaskDataSyncExecutionModel
from ...schemas.task_data_sync.execution_log import (
    TaskDataExecutionLogQuery,
    TaskDataContrastResultQuery,
    TaskDataContrastResultExport,
    TaskComparisonDataQuery
)
from ...utils.response_utils import success_response, error_response

router = APIRouter(prefix="/taskDataExecutionLog")

@router.post("/list")
async def list_execution_logs(
    query: TaskDataExecutionLogQuery = Body(...)
):
    """
    查询执行日志记录数据
    可根据任务ID、批次号、状态筛选，支持分页
    """
    try:
        # 查询记录
        results, total = await TaskDataSyncExecutionModel.query_execution_logs(
            task_id=query.taskId,
            batch_no=query.batchNo,
            status=query.status,
            page=query.page,
            page_size=query.size
        )
        
        return success_response(data={"list":results,"total":total})
    except Exception as e:
        return error_response(message=f"查询执行日志记录失败: {str(e)}", code=500)

@router.get("/tasks")
async def get_task_names():
    """
    获取所有任务名称列表，用于下拉选择
    """
    try:
        # 查询任务名称
        results = await TaskDataSyncExecutionModel.get_task_names()
        
        return success_response(data=results)
    except Exception as e:
        return error_response(message=f"获取任务名称列表失败: {str(e)}", code=500)

@router.post("/queryContrastRresultList")
async def query_contrast_results(
    query: TaskDataContrastResultQuery = Body(...)
):
    """
    查询对比结果
    根据执行日志ID获取该次执行的所有对比结果
    """
    try:
        # 查询记录
        results = await TaskDataSyncExecutionModel.query_contrast_results(
            execution_log_id=query.taskLogId
        )
        
        return success_response(data=results)
    except Exception as e:
        return error_response(message=f"查询对比结果失败: {str(e)}", code=500)

@router.get("/detail/{log_id}")
async def get_execution_log_detail(log_id: str):
    """
    获取执行日志详情
    """
    try:
        # 查询日志详情
        result = await TaskDataSyncExecutionModel.get_execution_log(log_id)
        
        if not result:
            return error_response(message="未找到日志记录", code=404)
            
        return success_response(data=result)
    except Exception as e:
        return error_response(message=f"获取日志详情失败: {str(e)}", code=500)

@router.post("/getPairedComparisonData")
async def get_paired_comparison_data(
    query: TaskComparisonDataQuery = Body(...)
):
    """
    获取配对的目标和源数据，支持分页加载
    返回目标数据和对应的源数据，以及不匹配的字段信息
    """
    try:
        # 获取配对数据
        result = await TaskDataSyncExecutionModel.get_paired_comparison_data(
            execution_log_id=query.taskLogId,
            offset=query.offset,
            limit=query.limit
        )
        
        return success_response(data=result)
    except Exception as e:
        return error_response(message=f"获取配对对比数据失败: {str(e)}", code=500)

@router.post("/exportContrastRresultList")
async def export_contrast_results(
    query: TaskDataContrastResultExport = Body(...)
):
    """
    导出对比结果
    将目标数据和源数据导出到Excel文件的两个sheet，对比不同的数据列使用黄色高亮
    """
    try:
        # 获取导出数据
        target_data, source_data, contrast_results = await TaskDataSyncExecutionModel.get_export_data(
            execution_log_id=query.taskLogId
        )
        
        # 如果没有数据
        if not target_data or not source_data:
            return error_response(message="未找到相关数据", code=404)
        
        # 创建一个字典，用于快速查找不匹配的列
        # 结构: {task_target_list_id: {column_name: True}}
        different_columns = {}
        for result in contrast_results:
            if not result["is_same"]:
                target_id = result["task_target_list_id"]
                column = result["column_name"]
                
                if target_id not in different_columns:
                    different_columns[target_id] = {}
                    
                different_columns[target_id][column] = True
        
        # 获取所有列名（从第一条数据中提取）
        if target_data and 'data' in target_data[0]:
            columns = list(target_data[0]['data'].keys())
        else:
            columns = []
            
        # 创建一个源数据ID到源数据的映射
        source_by_target_id = {item['task_target_list_id']: item for item in source_data}
        
        # 创建Excel文件
        output = io.BytesIO()
        
        # 使用openpyxl创建工作簿
        wb = Workbook()
        
        # 创建目标数据工作表
        ws_target = wb.active
        ws_target.title = "目标数据"
        
        # 添加表头
        for col_idx, column in enumerate(columns, start=1):
            ws_target.cell(row=1, column=col_idx, value=column)
        
        # 填充目标数据
        for row_idx, target_item in enumerate(target_data, start=2):
            target_id = target_item['_id']
            target_row = target_item['data']
            
            for col_idx, column in enumerate(columns, start=1):
                value = target_row.get(column)
                cell = ws_target.cell(row=row_idx, column=col_idx, value=value)
                
                # 检查是否需要高亮
                # 如果该单元格对应的列在不同的列中，设置黄色背景
                if target_id in different_columns and column in different_columns[target_id]:
                    cell.fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
        
        # 创建源数据工作表
        ws_source = wb.create_sheet(title="源数据")
        
        # 添加表头
        for col_idx, column in enumerate(columns, start=1):
            ws_source.cell(row=1, column=col_idx, value=column)
        
        # 填充源数据
        for row_idx, target_item in enumerate(target_data, start=2):
            target_id = target_item['_id']
            
            # 查找对应的源数据
            source_item = source_by_target_id.get(target_id)
            if source_item:
                source_row = source_item['data']
                
                for col_idx, column in enumerate(columns, start=1):
                    value = source_row.get(column)
                    cell = ws_source.cell(row=row_idx, column=col_idx, value=value)
                    
                    # 检查是否需要高亮
                    if target_id in different_columns and column in different_columns[target_id]:
                        cell.fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
            else:
                # 如果没有找到对应的源数据，填充空值
                for col_idx, column in enumerate(columns, start=1):
                    ws_source.cell(row=row_idx, column=col_idx, value=None)
        
        # 保存工作簿
        wb.save(output)
        output.seek(0)
        
        # 返回文件流
        return StreamingResponse(
            output,
            media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            headers={"Content-Disposition": "attachment; filename=contrast_results.xlsx"}
        )
    except Exception as e:
        return error_response(message=f"导出对比结果失败: {str(e)}", code=500)